<template>
    <!-- 单个组件封装   v-draggable  @mousedown="handleMouseDownOnPoint(item, $event)"-->
    <div class="shape " :class="{ active }" @mousedown="handleMouseDownComponent" v-draggable :style="zIndex">
        <i v-show="active" class="iconfont icon-rotate" @mousedown="handleRotate"></i>
        <i v-show="isLock" class="iconfont icon-lock"></i>
        <i v-show="active" v-for="item in pointList" :key="item" class="shape-point" :style="getPointStyle(item)"
            v-scaling="item">
        </i>
        <slot></slot>
    </div>
</template>

<script>
import { draggable, scaling } from '@/utils/directives'
import { mod360 } from '@/utils/translate'
import { mapState } from 'vuex'
export default {
    directives: {
        draggable,
        scaling
    },
    props: {
        // 是否选中该组件
        active: {
            type: Boolean,
            default: false,
        },
        // 组件对象
        element: {
            require: true,
            type: Object,
        },
        // 组件的样式
        defaultStyle: {
            require: true,
            type: Object,
        },
        // 组件的层级
        zIndex: {
            require: true,
            type: [Number, String],
        },
        // 组件是否上锁
        isLock: {
            type: Boolean,
            default: false
        }
    },
    computed: {
        ...mapState({
            curComponent: state => state.menu.curComponent || {}
        })
    },
    mounted() {
        this.cursors = this.getCursor()
    },
    data() {
        return {
            pointList: ['lt', 't', 'rt', 'r', 'rb', 'b', 'lb', 'l'], // 八个方向
            pointList2: ['r', 'l'], // 左右两个方向
            initialAngle: { // 每个点对应的初始角度
                lt: 0,
                t: 45,
                rt: 90,
                r: 135,
                rb: 180,
                b: 225,
                lb: 270,
                l: 315,
            },
            angleToCursor: [ // 每个范围的角度对应的光标
                { start: 338, end: 23, cursor: 'nw' },
                { start: 23, end: 68, cursor: 'n' },
                { start: 68, end: 113, cursor: 'ne' },
                { start: 113, end: 158, cursor: 'e' },
                { start: 158, end: 203, cursor: 'se' },
                { start: 203, end: 248, cursor: 's' },
                { start: 248, end: 293, cursor: 'sw' },
                { start: 293, end: 338, cursor: 'w' },
            ],
            cursors: {},
        }
    },
    methods: {
        handleMouseDownOnPoint(point, e) {
            e.stopPropagation()
            e.preventDefault()
            console.log(point, e)
        },
        // 鼠标按下选中当前元素
        handleMouseDownComponent(e) {
            e.stopPropagation()
            e.preventDefault()
            this.$store.commit('SELECT_CUR_COMPONENT', this.element)  //    鼠标按下选择当前元素
            this.$store.commit('HIDDEN_MENU')//关闭菜单
        },
        handleRotate() {
            console.log('旋转')
        },

        getCursor() {
            const { angleToCursor, initialAngle, pointList, element } = this
            const rotate = mod360(element.style.rotate) // 取余 360
            const result = {}
            let lastMatchIndex = -1 // 从上一个命中的角度的索引开始匹配下一个，降低时间复杂度
            pointList.forEach(point => {
                const angle = mod360(initialAngle[point] + rotate)
                const len = angleToCursor.length
                while (true) {
                    lastMatchIndex = (lastMatchIndex + 1) % len
                    const angleLimit = angleToCursor[lastMatchIndex]
                    if (angle < 23 || angle >= 338) {
                        result[point] = 'nw-resize'
                        return
                    }

                    if (angleLimit.start <= angle && angle < angleLimit.end) {
                        result[point] = angleLimit.cursor + '-resize'
                        return
                    }
                }
            })
            return result
        },
        getPointStyle(point) {
            const { width, height } = this.defaultStyle
            const hasT = /t/.test(point)
            const hasB = /b/.test(point)
            const hasL = /l/.test(point)
            const hasR = /r/.test(point)
            let newLeft = 0
            let newTop = 0
            // 四个角的点
            if (point.length === 2) {
                newLeft = hasL ? 0 : width
                newTop = hasT ? 0 : height
            } else {
                // 上下两点的点，宽度居中
                if (hasT || hasB) {
                    newLeft = width / 2
                    newTop = hasT ? 0 : height
                }

                // 左右两边的点，高度居中
                if (hasL || hasR) {
                    newLeft = hasL ? 0 : width
                    newTop = Math.floor(height / 2)
                }
            }

            const style = {
                marginLeft: '-4px',
                marginTop: '-4px',
                left: `${newLeft}px`,
                top: `${newTop}px`,
                cursor: this.cursors[point],
            }
            return style
        },
    }
}
</script>

<style lang="scss" scoped>
.shape {
    position: absolute;

    &:hover {
        cursor: move;
    }
}

.active {
    outline: 1px solid #70c0ff;
    user-select: none;
}

.shape-point {
    position: absolute;
    background: #fff;
    border: 1px solid #59c7f9;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    z-index: 1;
}

.icon-rotate {
    position: absolute;
    top: -30px;
    left: 50%;
    transform: translateX(-50%);
    cursor: grab;
    color: #59c7f9;
    font-size: 20px;
    font-weight: 600;

    &:active {
        cursor: grabbing;
    }
}

.icon-lock {
    position: absolute;
    top: -30px;
    right: 50%;
    z-index: 99999;
}
</style>